package wiki.kaizen.cloud.plugin.spring.scan.compent;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;
import wiki.kaizen.cloud.plugin.spring.scan.LogInfo;
import wiki.kaizen.cloud.plugin.spring.scan.annotation.Log;
import wiki.kaizen.cloud.plugin.spring.scan.handler.LogServiceHandler;
import wiki.kaizen.cloud.plugin.spring.util.MethodUtil;

import java.lang.reflect.Method;

/**
 *异步代理类
 *@Async 注解的实现都是基于Spring的AOP，AOP基于动态代理模式,
 *
 * 异步调用无法通过 RequestContextHolder.getRequestAttributes()获取request,这种方法只能在主线程取request
 *
 * this.method 调用@Async 注解方法 会使注解失效
 * */
@Component
@Async
public class AsyncProxyCompent {

    private final LogServiceHandler logServiceHandler;

    public AsyncProxyCompent(LogServiceHandler logServiceHandler) {
        this.logServiceHandler = logServiceHandler;
    }

    /**
     * 异步执行 日志处理方法
     * */
    public void logHandler(ProceedingJoinPoint point, long excuteTime,String ip){
        //获取执行方法
        Method method =  ((MethodSignature) point.getSignature()).getMethod();
        //获取注解
        Log log = method.getAnnotation(Log.class);
        if (log == null){
            return;
        }
        LogInfo info = LogInfo.builder()
                .clazz(point.getTarget().getClass())
                .excuteTime(excuteTime)
                .method(method)
                .args(
                        MethodUtil.getArgs(method.getParameters(),point.getArgs())
                )
                .value(log.value())
                .ip(ip)
                .build();
        logServiceHandler.log(info);
    }


}
